#----------------------------------------------------------------------------
# python metaWeblogAPI : pmwa.py 
#
# Author : Choonho Son (choonho.son@gmail.com)
#
# Copyright (C) 2007-, Choonho Son
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# See the file COPYING for a complete copy of the LGPL.
#-----------------------------------------------------------------------------

__version__ = "0.1"

__footer__ = """
<br>
<br>
Powered by <a href=http://code.google.com/p/pmwa/ target=_blank_>PMWA.</a>
<br>
"""
import xmlrpclib
import sys

#-------------------------------------
# metaWeblogapi interface URL
# TatterTools : http://www.example.com/tt/api
#
#-------------------------------------
xmlrpcurl="http://sunshout.cafe24.com/blog/api"


#--------------------------------------
# About MetaWeblogAPI
# Reference http://www.xmlrpc.com/metaWeblogApi
#
# 1. entry point
# 1.1 newPost (blogid, username, password, struct, publish) returns string
# 1.2 editPost(postid, username, password, struct, publish) returns true
# 1.3 getPost (postid, username, password) returns struct
#
# 2. struct
# same with element in RSS 2.0
#   -----------------------------------------------------
#   Element      Description            Example
#   -----------------------------------------------------
#   title       The title of item   Venice Film Festival
#   link        The URL of the item http://nytimes.com/2004/12/07FEST.html
#   description The item synopsis   contents (in Blog API)
#   author      Email address       oprah\@oxygen.net
#   category    
#   comments
#   enclosure   Describes a media object
#               that is attached to the item
#   guid        A string that uniquely 
#               itentifies the item
#   pubData     published data
#   source      The RSS channel that the item
#                came from
# 
# ****** In python, struct is dictionary ***********
#   key             Example
# -------------------------------------------------
#   permaLink       http://sunshout.cafe24.com/blog/
#   description     blala
#   title
#   mt_excerpt
#   userid
#   datePosted     <DateTime ''19700101T00:00:00' at 22f698>
#   content
#   link
#   mt_allow_comments
#   dateCreated
#   postid
#   dateModified
#   categories    
#   mt_allow_pings
#
#  To Do List
#  1) explain struct
#
methods={}


def getServer():
    return xmlrpclib.Server(xmlrpcurl).metaWeblog

#---------------------------------------
# change channel in rss2.0 to struct
# 
# channel           -->    struct
# --------------------------------
# channel:title            title
# item:title               description:head
# item:link                description:link
# item:description         description:content
#
#
# parameter
#   channel : XML string
def channel2struct(channel):
    from xml.dom.minidom import parseString
    root = parseString(channel)
    struct = {}
    #-----------
    # title
    #-----------
    t_title = root.getElementsByTagName('title')[0].firstChild.data
    struct['title'] = t_title.encode('utf-8')

    #--------------
    # description
    #--------------
    result = ''
    n_item = root.getElementsByTagName('item')
    for index in n_item:
        t_head = index.getElementsByTagName('title')[0].firstChild.data
        t_link = index.getElementsByTagName('link')[0].firstChild.data
        t_content = index.getElementsByTagName('description')[0].firstChild.data
        result = result \
                 + "<a href=" + t_link + " target=_blank_>" \
                 + t_head + "</a><br>"\
                 + t_content + "<br><br>"

    struct['description'] = result.encode('utf-8')

    return struct

#----------------------------------
# new post
#----------------------------------
def newpost(account, struct):
    """Post an entry on webblog site."""
    # add footer message
    struct['description'] = struct['description'] + __footer__

    postid = getServer().newPost("", account[0], account[1], struct, True)
    return postid

# register as "NEW"
methods["NEW"]=newpost
        
#-------------------------------------
# edit post
#-------------------------------------
def editpost(account, args):
    """Edit an existed entry """
    
    struct = {"title":args[1], "categories":[args[2]],
              "description":args[3]}
    # "description":publish(args[3])}
    # editPost(postId, username, password,
    #          {title, description, categories}, publish)
    ret = getServer().editPost(args[0], account[0], account[1], struct, True)
    print "modified post has be saved"

# register as "EDIT"
methods["EDIT"]=editpost

#-------------------------------------
# get post
#-------------------------------------
def getpost(account, args):
    """get an post from args
    args = post number
    """
    # getPost(postid, username, password)
    # return struct
    struct = getServer().getPost(args[0], account[0], account[1])
    return struct

methods["GET"]=getpost

#----------------------------------------
# get categories if exist
#----------------------------------------
def getcategories(account, args):
    """get categories if exist"""
    # getCategories(blogid, username, password)
    # return list of struct
    # struct = {description, htmlURL, rssURL element}
    category_list = getServer().getCategories('',account[0], account[1])
    return category_list

methods["CATEGORIES"] = getcategories

#----------------------------------------
# attach media object
#----------------------------------------
def newmediaobject(account, args):
    """Upload an multimedia to blog site."""
    
    struct = {"name":args[0], "type":type[1], "bits":bits[2]}
    # newMediaObject(postId, username, password,
    #                {name, type, bits})
    upload = getServer().newMediaObject("", account[0], account[1], struct)
    print "url of upload:", upload["url"]

# register as "MEDIA"
methods["MEDIA"]=newmediaobject


def getrecentposts(account, args):
    """Get recently posted entries."""

    # getRecentPosts(postid, username, password, numposts)
    posts = getServer().getRecentPosts("", account[0], account[1],
                                      len(args) == 0 and 5 or int(args[0]))
    # pretty print posts
    import time
    for p in posts:
        print 
        print "postid:", p["postid"]
        print "title:", p["title"]
        print "created date:", \
            time.strftime("%Y-%m-%d", \
            time.strptime(p["dateCreated"].value, "%Y%m%dT%H:%M:%S"))

# register as "LIST"
methods["LIST"]=getrecentposts
        


if __name__ == "__main__":
    # ---------------------------------------------
    # use if you want get from command line
    # ---------------------------------------------
    #method = sys.argv[1]
    #args = sys.argv[2:]

    #-----------------------
    # TatterTools (ID, PW)
    # 
    # ex) account = ['haha@paran.com', 'hahapassword']
    #-----------------------
    

    
    #---------------------------
    # example post's content
    # if category name is not correct,
    # then post without category
    #---------------------------
    method = "NEW"
    mytitle = 'Automatic Fund crawler'
    mycategories = 'Asset/Fund'
    mytext = """
<b>some contents</b>
html does not work
<h1>test</h1>
"""
    #--------------------------------
    # to post html
    # contents must be enclosed by ''
    #--------------------------------

    args = [mytitle,mycategories,mytext]
    methods[method](account, args)

    #-------------------------------------
    # example : get post
    # post number : http://sunshout.cafe24.com/blog/128
    # 
    #-------------------------------------
    #print methods["GET"](account,[128])


    #-------------------------------------
    # example : get categories list
    #-------------------------------------
    #print methods["CATEGORIES"](account,[])
